<?php

namespace iBrand\Shop\Backend\Http\Controllers;

use Encore\Admin\Facades\Admin as LaravelAdmin;
use Encore\Admin\Layout\Content;
use iBrand\Component\Goods\Models\Goods;
use iBrand\Component\Goods\Models\GoodsCategory;
use iBrand\Component\Goods\Models\GoodsProduct;
use iBrand\Component\Goods\Models\Season;
use iBrand\Component\Goods\Models\SpecsValue;
use iBrand\Component\Goods\Models\Style;
use iBrand\Component\Purchase\Models\TakeStockItem;
use iBrand\Shop\Backend\Repository\O2oGoodsProductsRepository;
use iBrand\Shop\Backend\Service\CommonService;
use iBrand\Shop\Backend\Service\TakeStockService;

class TakeStockReportController extends Controller
{
	protected $commonService;
	protected $o2oGoodsProductsRepository;
	protected $takeStockService;
	protected $cache;

	public function __construct(CommonService $commonService,
	                            O2oGoodsProductsRepository $o2oGoodsProductsRepository,
	                            TakeStockService $takeStockService)
	{
		$this->commonService              = $commonService;
		$this->o2oGoodsProductsRepository = $o2oGoodsProductsRepository;
		$this->takeStockService           = $takeStockService;
		$this->cache                      = cache();
	}

	/**
	 * 盘点报表
	 *
	 * @return \Encore\Admin\Layout\Content
	 */
	public function index()
	{
		$brandList     = $this->commonService->getBrandList();
		$years         = $this->commonService->getYearList();
		$categoryList  = $this->commonService->getCategoryList();
		$clerks        = $this->commonService->getClerkList();
		$specList      = $this->commonService->getSpecList();
		$categories    = $categoryList['categories'];
		$allCategories = $categoryList['allCategories'];
		$seasons       = Season::all()->toArray();
		$styles        = Style::all()->toArray();
		$colors        = $specList['colors'];
		$sizes         = $specList['sizes'];

		return LaravelAdmin::content(function (Content $content) use ($brandList, $years, $clerks, $categories, $allCategories, $seasons, $styles, $colors, $sizes) {

			$content->header('盘点报表');

			$content->breadcrumb(
				['text' => '报表', 'url' => 'warehouse/report/purchase', 'no-pjax' => 1],
				['text' => '盘点报表', 'url' => '', 'no-pjax' => 1, 'left-menu-active' => '盘点报表']

			);

			$content->body(view('shop-backend::takeStockReport.index', compact('brandList', 'years', 'clerks', 'categories', 'allCategories', 'seasons', 'styles', 'colors', 'sizes')));
		});
	}

	public function storeRecordDetailList()
	{
		$condition   = $this->searchCondition();
		$where       = $condition[0];
		$time        = $condition[1];
		$product_ids = $condition[3];
		$stock       = $where['stock'];
		unset($where['stock']);
		$goods_ids = $condition[2];
		if (empty($goods_ids)) {
			$item_ids = [];
		} elseif ($goods_ids === [0]) {
			$item_ids = [0];
		} else {
			$tmpWhere = $where;
			unset($tmpWhere['created_at']);
			$tmpWhere['shop_id'] = $stock['shop_id'];
			$o2oGoodsProduct     = $this->o2oGoodsProductsRepository->getGoodsProductsPaginate($tmpWhere, $goods_ids, [], 0);
			if ($o2oGoodsProduct && $o2oGoodsProduct->count() > 0) {
				$item_ids = $o2oGoodsProduct->pluck('product_id')->toArray();
			} else {
				$item_ids = [0];
			}
		}

		$list = $this->takeStockService->getStoreRecordDetailList($where, $time, $stock, $item_ids, $product_ids);

		return $list->toJson();
	}

	public function storeRecordGroupByOrderList()
	{
		$condition = $this->searchCondition();
		$where     = $condition[0];
		$time      = $condition[1];
		$stock     = $where['stock'];
		unset($where['stock']);

		if (isset($stock['shop_id']) && $stock['shop_id']) {
			$where['shop_id'] = $stock['shop_id'];
		}

		if (isset($stock['clerk_id']) && $stock['clerk_id']) {
			$where['clerk_id'] = $stock['clerk_id'];
		}

		if (isset($stock['code']) && !empty($stock['code'])) {
			$where['code'] = $stock['code'];
		}

		$list = $this->takeStockService->getStoreRecordGroupByOrderList($where, $time);

		return $list->toJson();
	}

	public function storeRecordGroupByGoodList()
	{
		$condition = $this->searchCondition();
		$where     = $condition[0];
		$time      = $condition[1];
		$ids       = $condition[2];
		$stock     = $where['stock'];
		unset($where['stock']);
		if (empty($ids)) {
			$goods_ids = [];
		} elseif ($ids === [0]) {
			$goods_ids = [0];
		} else {
			$goods_ids = $ids;
		}

		$list = $this->takeStockService->getStoreRecordGroupByGoodList($where, $time, $stock, $goods_ids);

		return $list->toJson();
	}

	private function searchCondition()
	{
		$where['stock']['shop_id'] = session('shop_id');
		$time                      = [];
		if (request('orderNo')) {
			$where['stock']['code'] = ['like', '%' . request('orderNo') . '%'];
		}

		if (request('userId')) {
			$where['stock']['clerk_id'] = request('userId');
		}

		$beginTime = '';
		if (request('beginTime')) {
			$beginTime = date('Y-m-d', strtotime(request('beginTime'))) . ' 00:00:00';
		}

		$endTime = '';
		if (request('endTime')) {
			$endTime = date('Y-m-d', strtotime(request('endTime'))) . ' 23:59:59';
		}

		if (!empty(request('beginTime')) && !empty(request('endTime'))) {
			$where['created_at'] = ['<=', $endTime];
			$time['created_at']  = ['>=', $beginTime];
		}

		if (!empty(request('endTime'))) {
			$time['created_at'] = ['<=', $endTime];
		}

		if (!empty(request('beginTime'))) {
			$time['created_at'] = ['>=', $beginTime];
		}

		$search_goods_ids = [];
		$brand_search     = false;
		$brand_goods_ids  = [];
		if (request('blandId')) {
			$brand_search = true;
			$goodsList    = Goods::where('brand_id', request('blandId'))->get();
			if ($goodsList && $goodsList->count() > 0) {
				$brand_goods_ids = $goodsList->pluck('id')->toArray();
				sort($brand_goods_ids);
			}
		}

		$search_goods_ids[] = ['goods_ids' => $brand_goods_ids, 'is_search' => $brand_search];
		$style_search       = false;
		$style_goods_ids    = [];
		if (request('styleId')) {
			$style_search = true;
			$goodsList    = Goods::where('style_id', request('styleId'))->get();
			if ($goodsList && $goodsList->count() > 0) {
				$style_goods_ids = $goodsList->pluck('id')->toArray();
				sort($style_goods_ids);
			}
		}

		$search_goods_ids[] = ['goods_ids' => $style_goods_ids, 'is_search' => $style_search];
		$year_search        = false;
		$year_goods_ids     = [];
		if (request('year')) {
			$year_search = true;
			$goodsList   = Goods::where('year', request('year'))->get();
			if ($goodsList && $goodsList->count() > 0) {
				$year_goods_ids = $goodsList->pluck('id')->toArray();
				sort($year_goods_ids);
			}
		}

		$search_goods_ids[] = ['goods_ids' => $year_goods_ids, 'is_search' => $year_search];
		$season_search      = false;
		$season_goods_ids   = false;
		if (request('seasonId')) {
			$season_search = true;
			$goodsList     = Goods::where('season_id', request('seasonId'))->get();
			if ($goodsList && $goodsList->count() > 0) {
				$season_goods_ids = $goodsList->pluck('id')->toArray();
				sort($season_goods_ids);
			}
		}

		$search_goods_ids[] = ['goods_ids' => $season_goods_ids, 'is_search' => $season_search];
		$a_is_search        = false;
		$a_goods_ids        = [];
		if (request('searchKey')) {
			$a_is_search = true;
			$goods       = Goods::where('name', 'like', '%' . request('searchKey') . '%')->orWhere('goods_no', 'like', '%' . request('searchKey') . '%')->get();
			if ($goods && $goods->count() > 0) {
				$a_goods_ids = $goods->pluck('id')->toArray();
				$a_goods_ids = array_unique($a_goods_ids);
				sort($a_goods_ids);
			}
		}

		$search_goods_ids[] = ['goods_ids' => $a_goods_ids, 'is_search' => $a_is_search];
		$b_is_search        = false;
		$b_goods_ids        = [];
		if (request('categoryId')) {
			$b_is_search    = true;
			$category_goods = GoodsCategory::where('category_id', request('categoryId'))->get();
			if ($category_goods && $category_goods->count() > 0) {
				$b_goods_ids = $category_goods->pluck('goods_id')->toArray();
				$b_goods_ids = array_unique($b_goods_ids);
				sort($b_goods_ids);
			}
		}

		$search_goods_ids[] = ['goods_ids' => $b_goods_ids, 'is_search' => $b_is_search];
		$spec_goods_ids     = [];
		$c_is_search        = false;
		$tmpGoodsProduct    = GoodsProduct::where('is_show', 1)->first();
		$tmpSpec            = SpecsValue::find($tmpGoodsProduct->specID[0]);
		if ($tmpSpec->spec_id == 1) {
			$left_type = 'size';
		} elseif ($tmpSpec->spec_id == 2) {
			$left_type = 'color';
		}

		$product_ids = [];
		if (request('colorId') && !request('sizeId')) {
			$c_is_search = true;
			$like        = $left_type == 'color' ? '["' . request('colorId') . '"%' : '%"' . request('colorId') . '"]';
			$products    = GoodsProduct::where('is_show', 1)->where('specID', 'like', $like)->get();
			if ($products && $products->count() > 0) {
				$spec_goods_ids = $products->pluck('goods_id')->toArray();
				$product_ids    = $products->pluck('id')->toArray();
			}
		} elseif (!request('colorId') && request('sizeId')) {
			$c_is_search = true;
			$like        = $left_type == 'size' ? '["' . request('sizeId') . '"%' : '%"' . request('sizeId') . '"]';
			$products    = GoodsProduct::where('is_show', 1)->where('specID', 'like', $like)->get();
			if ($products && $products->count() > 0) {
				$spec_goods_ids = $products->pluck('goods_id')->toArray();
				$product_ids    = $products->pluck('id')->toArray();
			}
		} elseif (request('colorId') && request('sizeId')) {
			$c_is_search = true;
			$like        = $left_type == 'color' ? '["' . request('colorId') . '","' . request('sizeId') . '"]' : '["' . request('sizeId') . '","' . request('colorId') . '"]';
			$products    = GoodsProduct::where('is_show', 1)->where('specID', $like)->get();
			if ($products && $products->count() > 0) {
				$spec_goods_ids = $products->pluck('goods_id')->toArray();
				$product_ids    = $products->pluck('id')->toArray();
			}
		}

		if (!empty($spec_goods_ids)) {
			$spec_goods_ids = array_unique($spec_goods_ids);
			sort($spec_goods_ids);
		}

		$search_goods_ids[] = ['goods_ids' => $spec_goods_ids, 'is_search' => $c_is_search];
		$goods_ids          = [];
		if (!empty($search_goods_ids)) {
			$collect_goods       = collect($search_goods_ids);
			$filter_false_search = $collect_goods->filter(function ($item) {
				return $item['is_search'] === false;
			});

			if ($filter_false_search->count() != $collect_goods->count()) {
				$filter_empty_goods = $collect_goods->filter(function ($item) {
					return $item['is_search'] && empty($item['goods_ids']);
				});

				if ($filter_empty_goods->count() <= 0) {
					$filter_goods = $collect_goods->filter(function ($item) {
						return $item['is_search'] && !empty($item['goods_ids']);
					});

					if ($filter_goods->count() > 0) {
						$filter_goods = array_column($filter_goods->values()->toArray(), 'goods_ids');
						$tmp          = [];
						$tmp_count    = 0;
						foreach ($filter_goods as $value) {
							if (empty($tmp) && $tmp_count == 0) {
								$tmp = $value;
							} else {
								$tmp = array_intersect($tmp, $value);
							}

							$tmp_count++;
						}

						if (!empty($tmp)) {
							$goods_ids = $tmp;
						} else {
							$goods_ids = [0];
						}
					}
				} else {
					$goods_ids = [0];
				}
			}
		}

		return [$where, $time, $goods_ids, $product_ids];
	}

	public function storeDetailListExcel()
	{
		$condition    = $this->searchCondition();
		$where        = $condition[0];
		$time         = $condition[1];
		$searchParams = request()->all();
		$dataListType = $searchParams['dataListType'];

		$prefix = '';
		$data   = [];
		switch ($dataListType) {
			case 'storeRecordDetailList':
				$product_ids = $condition[3];
				$stock       = $where['stock'];
				unset($where['stock']);
				$goods_ids = $condition[2];
				if (empty($goods_ids)) {
					$item_ids = [];
				} elseif ($goods_ids === [0]) {
					$item_ids = [0];
				} else {
					$tmpWhere = $where;
					unset($tmpWhere['created_at']);
					$tmpWhere['shop_id'] = $stock['shop_id'];
					$o2oGoodsProduct     = $this->o2oGoodsProductsRepository->getGoodsProductsPaginate($tmpWhere, $goods_ids, [], 0);
					if ($o2oGoodsProduct && $o2oGoodsProduct->count() > 0) {
						$item_ids = $o2oGoodsProduct->pluck('product_id')->toArray();
					} else {
						$item_ids = [0];
					}
				}

				$list   = $this->takeStockService->getStoreRecordDetailList($where, $time, $stock, $item_ids, $product_ids);
				$prefix = '盘点明细_';
				$data   = $this->takeStockService->getStoreRecordDetailExportData($list);

				break;
			case 'groupByOrderList':
				$stock = $where['stock'];
				unset($where['stock']);

				if (isset($stock['shop_id']) && $stock['shop_id']) {
					$where['shop_id'] = $stock['shop_id'];
				}

				if (isset($stock['clerk_id']) && $stock['clerk_id']) {
					$where['clerk_id'] = $stock['clerk_id'];
				}

				if (isset($stock['code']) && !empty($stock['code'])) {
					$where['code'] = $stock['code'];
				}

				$list   = $this->takeStockService->getStoreRecordGroupByOrderList($where, $time);
				$prefix = '按盘点单汇总_';
				$data   = $this->takeStockService->getStoreRecordGroupByOrderExportData($list);

				break;
			case 'groupByGoodList':
				$ids   = $condition[2];
				$stock = $where['stock'];
				unset($where['stock']);
				if (empty($ids)) {
					$goods_ids = [];
				} elseif ($ids === [0]) {
					$goods_ids = [0];
				} else {
					$goods_ids = $ids;
				}

				$list   = $this->takeStockService->getStoreRecordGroupByGoodList($where, $time, $stock, $goods_ids);
				$prefix = '按商品汇总_';
				$data   = $this->takeStockService->getStoreRecordGroupByGoodExportData($list);

				break;
		}

		$page     = request('page') ? request('page') : 1;
		$limit    = request('limit') ? request('limit') : 20;
		$type     = request('type');
		$lastPage = $list->lastPage();
		if ($page == 1) {
			session(['export_take_stock_list_cache_' . $dataListType => generate_export_cache_name('export_take_stock_list_cache_' . $dataListType . '_')]);
		}

		$cacheName = session('export_take_stock_list_cache_' . $dataListType);
		if ($this->cache->has($cacheName)) {
			$cacheData = $this->cache->get($cacheName);
			$this->cache->put($cacheName, array_merge($cacheData, $data), 300);
		} else {
			$this->cache->put($cacheName, $data, 300);
		}

		if ($page == $lastPage) {
			$title = [];
			switch ($dataListType) {
				case 'storeRecordDetailList':
					$title = $this->takeStockService->getStoreRecordDetailExportTitle();
					break;
				case 'groupByOrderList':
					$title = $this->takeStockService->getStoreRecordGroupByOrderExportTile();
					break;
				case 'groupByGoodList':
					$title = $this->takeStockService->getStoreRecordGroupByGoodExportTitle();
					break;
			}

			return $this->ajaxJson(true, ['status' => 'done', 'url' => '', 'type' => $type, 'title' => $title, 'cache' => $cacheName, 'prefix' => $prefix]);
		} else {
			$url_bit = route('admin.shop.report.take.stock.storeDetailListExcel', array_merge(['page' => $page + 1, 'limit' => $limit], request()->except('page', 'limit')));

			return $this->ajaxJson(true, ['status' => 'goon', 'url' => $url_bit, 'page' => $page, 'totalPage' => $lastPage]);
		}
	}

	public function storeRecordDetailListSum()
	{
		$condition = $this->searchCondition();
		$where     = $condition[0];
		$time      = $condition[1];

		$skuCount        = 0;
		$goodsCount      = 0;
		$sumprofitNumber = 0;
		$sumProfitAmount = 0;

		$dataListType = request('dataListType');
		switch ($dataListType) {
			case 'storeRecordDetailList':
				$product_ids = $condition[3];
				$stock       = $where['stock'];
				unset($where['stock']);
				$goods_ids = $condition[2];
				if (empty($goods_ids)) {
					$item_ids = [];
				} elseif ($goods_ids === [0]) {
					$item_ids = [0];
				} else {
					$tmpWhere = $where;
					unset($tmpWhere['created_at']);
					$tmpWhere['shop_id'] = $stock['shop_id'];
					$o2oGoodsProduct     = $this->o2oGoodsProductsRepository->getGoodsProductsPaginate($tmpWhere, $goods_ids, [], 0);
					if ($o2oGoodsProduct && $o2oGoodsProduct->count() > 0) {
						$item_ids = $o2oGoodsProduct->pluck('product_id')->toArray();
					} else {
						$item_ids = [0];
					}
				}

				$list            = $this->takeStockService->getStoreRecordDetailList($where, $time, $stock, $item_ids, $product_ids, 0);
				$skuCount        = $list->pluck('item_id')->unique()->count();
				$goodsCount      = $list->pluck('goods_id')->unique()->count();
				$sumprofitNumber = $list->sum('difference_count');
				$sumProfitAmount = $list->sum('difference_amount');
				break;
			case 'groupByOrderList':
				$stock = $where['stock'];
				unset($where['stock']);

				if (isset($stock['shop_id']) && $stock['shop_id']) {
					$where['shop_id'] = $stock['shop_id'];
				}

				if (isset($stock['clerk_id']) && $stock['clerk_id']) {
					$where['clerk_id'] = $stock['clerk_id'];
				}

				if (isset($stock['code']) && !empty($stock['code'])) {
					$where['code'] = $stock['code'];
				}

				$list            = $this->takeStockService->getStoreRecordGroupByOrderList($where, $time, 0);
				$skuCount        = TakeStockItem::whereIn('take_stock_id', $list->pluck('id'))->pluck('item_id')->unique()->count();
				$goodsCount      = TakeStockItem::whereIn('take_stock_id', $list->pluck('id'))->pluck('goods_id')->unique()->count();
				$sumprofitNumber = $list->sum('difference_count');
				$sumProfitAmount = $list->sum('difference_amount');
				break;
			case 'groupByGoodList':
				$ids   = $condition[2];
				$stock = $where['stock'];
				unset($where['stock']);
				if (empty($ids)) {
					$goods_ids = [];
				} elseif ($ids === [0]) {
					$goods_ids = [0];
				} else {
					$goods_ids = $ids;
				}

				$list            = $this->takeStockService->getStoreRecordGroupByGoodList($where, $time, $stock, $goods_ids);
				$skuCount        = TakeStockItem::whereIn('goods_id', $list->pluck('goods_id')->all())->pluck('item_id')->unique()->count();
				$goodsCount      = $list->count();
				$sumprofitNumber = $list->sum('total_difference_count');
				$sumProfitAmount = $list->sum('total_difference_amount');
				break;
		}

		return response()->json(['goodsCount' => $goodsCount, 'skuCount' => $skuCount, 'storeHouseCount' => 0, 'sumProfitAmount' => $sumProfitAmount, 'sumprofitNumber' => $sumprofitNumber]);
	}
}